Skip to content

docs: document useSyncExternalStore pattern for reactive auth state#259

Merged
panz3r merged 4 commits intomainfrom
copilot/add-usage-example-sync-external-store
Apr 4, 2026
Merged

docs: document useSyncExternalStore pattern for reactive auth state#259
panz3r merged 4 commits intomainfrom
copilot/add-usage-example-sync-external-store

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 4, 2026

Affected Package(s)

  • @forward-software/react-auth (lib)
  • @forward-software/react-auth-google (packages/google-signin)
  • Examples
  • CI/CD / Repository configuration

Related Issue(s)

Closes #253

Motivation

EnhancedAuthClient.subscribe and getSnapshot are purpose-built for useSyncExternalStore, but this was never documented. Without it, consumers are likely to reach for fragile loading-state workarounds that miss auth state changes in multi-component layouts.

Description of Changes

  • Added a "Reactive auth state with useSyncExternalStore" section to lib/README.md as a ##### subsection correctly nested under #### EnhancedAuthClient, directly after the methods list:
    • Calls out subscribe/getSnapshot as the recommended pattern for reading auth state in components
    • Explains the bound arrow-function property design (safe to pass directly — no wrapper needed)
    • Provides a complete TSX example covering init guard, auth guard, and token access
    • Documents the snapshot shape (isInitialized, isAuthenticated, tokens) accurately: tokens is an empty object {} when no tokens are available (e.g. before login or after logout), never null
    • Clarifies that only successful login(), refresh(), logout(), and initialization operations update the auth state and trigger re-renders (matching the actual implementation where setState is only called on the success path)
import { useSyncExternalStore } from 'react';
import { authClient } from './auth'; // the authClient returned by createAuth

function MyComponent() {
  const { isInitialized, isAuthenticated, tokens } = useSyncExternalStore(
    authClient.subscribe,
    authClient.getSnapshot,
  );

  if (!isInitialized) return <LoadingSpinner />;
  if (!isAuthenticated) return <LoginPage />;

  return <Dashboard tokens={tokens} />;
}

Breaking Changes

None

How to Test

  1. CI Checks: Verify that all automated tests (Vitest) and build steps pass successfully on this PR.
  2. Local Verification (Optional):
    • Run pnpm install to install dependencies.
    • Run pnpm --filter @forward-software/react-auth test to run tests for the affected package.
    • Run pnpm --filter @forward-software/react-auth build to verify the build succeeds.
    • Run pnpm --filter @forward-software/react-auth lint to check for linting errors.

Checklist

  • My code follows the project's style guidelines
  • I have added or updated tests to cover the changes
  • I have updated relevant documentation
  • All tests are passing locally
  • CI checks are passing
  • I have reviewed my own code and lock file changes
  • I have checked for any potential security implications
  • I have verified the changes work as expected
  • My commit messages follow Conventional Commits format

Notes for Reviewers

Docs-only change — no source files modified, all 46 existing tests pass. The example uses authClient (the exact key returned by createAuth()) to stay consistent with the established API naming.

Copilot AI changed the title [WIP] Add usage example for useSyncExternalStore pattern in README docs: document useSyncExternalStore pattern for reactive auth state Apr 4, 2026
Copilot AI requested a review from panz3r April 4, 2026 14:08
@panz3r panz3r requested review from Copilot and removed request for panz3r April 4, 2026 14:41
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the @forward-software/react-auth package documentation to describe the intended React useSyncExternalStore integration pattern for consuming reactive auth state from EnhancedAuthClient.

Changes:

  • Added a “Reactive auth state with useSyncExternalStore” section to lib/README.md.
  • Included a TSX example showing initialization/auth guards and token usage via subscribe/getSnapshot.
  • Documented the snapshot fields and described what operations trigger re-renders.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@panz3r
Copy link
Copy Markdown
Member

panz3r commented Apr 4, 2026

@copilot look into the review comments and apply suggestions that look appropriate/correct

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 4, 2026

@copilot look into the review comments and apply suggestions that look appropriate/correct

Applied all three suggestions in commit 14183ce:

  • Heading level: Changed ######### so the section nests correctly under #### EnhancedAuthClient
  • tokens description: Removed the incorrect null claim; now accurately says "empty object {} when no tokens are available (e.g. before login or after logout)"
  • Re-render trigger: Changed "any call" → "Successful login(), refresh(), logout(), and initialization update the auth state…" to match the actual implementation (logout only calls setState on the success path)

Copilot AI requested a review from panz3r April 4, 2026 15:29
@panz3r panz3r marked this pull request as ready for review April 4, 2026 15:37
@panz3r panz3r merged commit 0d13a23 into main Apr 4, 2026
16 checks passed
@panz3r panz3r deleted the copilot/add-usage-example-sync-external-store branch April 4, 2026 15:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs: useSyncExternalStore pattern undocumented for consumers docs: no documented convention for how examples reference the core lib

3 participants